

package com.jf.cloud.biz.service.impl;

import cn.binarywang.wx.miniapp.bean.WxMaTemplateData;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.jf.cloud.api.auth.constant.SysTypeEnum;
import com.jf.cloud.api.multishop.bo.EsShopDetailBO;
import com.jf.cloud.api.multishop.feign.ShopDetailFeignClient;
import com.jf.cloud.api.platform.config.FeignShopConfig;
import com.jf.cloud.api.supplier.bo.SupplierDetailBO;
import com.jf.cloud.api.supplier.feign.SupplierDetailFeignClient;
import com.jf.cloud.api.user.feign.UserFeignClient;
import com.jf.cloud.api.user.vo.UserApiVO;
import com.jf.cloud.biz.config.WxConfig;
import com.jf.cloud.biz.constant.NotifyType;
import com.jf.cloud.biz.constant.RemindType;
import com.jf.cloud.biz.dto.WxMpMessage;
import com.jf.cloud.biz.dto.WxMpTemplateData;
import com.jf.cloud.biz.model.NotifyLog;
import com.jf.cloud.biz.service.*;
import com.jf.cloud.biz.vo.NotifyParamVO;
import com.jf.cloud.biz.vo.NotifyTemplateRemindVO;
import com.jf.cloud.biz.vo.NotifyTemplateVO;
import com.jf.cloud.common.constant.Constant;
import com.jf.cloud.common.constant.SendTypeEnum;
import com.jf.cloud.common.constant.StatusEnum;
import com.jf.cloud.common.order.vo.SendNotifyBO;
import com.jf.cloud.common.response.ServerResponseEntity;
import ma.glasnost.orika.MapperFacade;
import me.chanjar.weixin.common.error.WxErrorException;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.BooleanUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;


/**
 * 统一发送通知的事件
 *
 * @author zz
 */
@Service
public class SendMessageServiceImpl implements SendMessageService {

    private static final Logger logger = LoggerFactory.getLogger(SendMessageServiceImpl.class);

    @Autowired
    private NotifyLogService notifyLogService;
    @Autowired
    private SmsLogService smsLogService;
    @Autowired
    private FeignShopConfig feignShopConfig;
    @Autowired
    private WxConfig wxConfig;
    @Autowired
    private MapperFacade mapperFacade;
    @Autowired
    private NotifyTemplateService notifyTemplateService;
    @Autowired
    private ShopDetailFeignClient shopDetailFeignClient;

    @Autowired
    private SupplierDetailFeignClient supplierDetailFeignClient;
    @Autowired
    private UserFeignClient userFeignClient;
    @Autowired
    private NotifyTemplateRemindService notifyTemplateRemindService;

    @Override
    public void sendMsg(NotifyParamVO notifyParamVO) {
        if (Objects.isNull(notifyParamVO)) {
            return;
        }
        //发送给供应商的消息提醒
        SupplierDetailBO supplierDetailBO = new SupplierDetailBO();
        if (Objects.isNull(notifyParamVO.getShopId()) && Objects.nonNull(notifyParamVO.getSupplierId())) {
            supplierDetailBO = supplierDetailFeignClient.getSupplierBySupplierId(notifyParamVO.getSupplierId()).getData();
        }
        EsShopDetailBO shopDetailBO = shopDetailFeignClient.getShopByShopId(notifyParamVO.getShopId()).getData();
        String shopName = "";
        if (Objects.equals(notifyParamVO.getShopId(), Constant.PLATFORM_SHOP_ID)) {
            shopName = Constant.PLATFORM_SHOP_NAME;
        } else {
            shopName = Objects.nonNull(notifyParamVO.getShopId()) ? shopDetailBO.getShopName() : supplierDetailBO.getSupplierName();
        }
        notifyParamVO.setShopName(shopName);
        // 判断是什么类型，如果是发送给商家的，则修改手机号码，并且只需要推送手机号码即可
        SendTypeEnum sendTypeEnum = SendTypeEnum.instance(notifyParamVO.getSendType());
        logger.info(shopName + "消息类型" + notifyParamVO.getSendType());
        if (Objects.nonNull(sendTypeEnum) && Objects.equals(sendTypeEnum.getType(), SendTypeEnum.RECEIPT_ORDER.getType())) {
            notifyParamVO.setMobile(shopDetailBO.getContactPhone());
        }
        //获取模板的发送方式，获取商家选择的发送方式
        NotifyTemplateVO template = notifyTemplateService.getBySendType(notifyParamVO.getSendType());
        //是否开启消息提醒
        Boolean notifyLogStatus = false;

        //判断商家端和供应商的消息提醒设置
        Integer sysType = Objects.nonNull(notifyParamVO.getShopId()) ? SysTypeEnum.MULTISHOP.value() : SysTypeEnum.SUPPLIER.value();
        Long tenantId = Objects.nonNull(notifyParamVO.getShopId()) ? notifyParamVO.getShopId() : notifyParamVO.getSupplierId();
        NotifyTemplateRemindVO notifyTemplateRemindVO = notifyTemplateRemindService.getByTemplateIdAndShopIdAndSysType(template.getTemplateId(), tenantId, sysType);
        if (Objects.isNull(template) || Objects.equals(template.getStatus(), StatusEnum.DISABLE.value())) {
            return;
        }
        //设置关闭消息提醒 则生不成消息记录
        if (Objects.nonNull(notifyTemplateRemindVO) && Objects.equals(notifyTemplateRemindVO.getIsRemind(), RemindType.CLOSED.value())) {
            notifyLogStatus = true;
        }
        // 截取字符串,处理过长商品名称
        if (StrUtil.isNotBlank(notifyParamVO.getSpuName())) {
            notifyParamVO.setSpuName(notifyParamVO.getSpuName().substring(0, Math.min(14, notifyParamVO.getSpuName().length() - 1)) + "等商品");
        }
        // 处理数据
        notifyParamVO.setShopId(tenantId);
        notifyParamVO.setHour(Objects.isNull(notifyParamVO.getHour()) ? 0 : notifyParamVO.getHour());
        notifyParamVO.setProdNum(Objects.isNull(notifyParamVO.getProdNum()) ? 0 : notifyParamVO.getProdNum());
        notifyParamVO.setGroupCount(Objects.isNull(notifyParamVO.getGroupCount()) ? 0 : notifyParamVO.getGroupCount());
        notifyParamVO.setPrice(Objects.isNull(notifyParamVO.getPrice()) ? 0.0 : notifyParamVO.getPrice());
        notifyParamVO.setPayType(Objects.isNull(notifyParamVO.getPayType()) ? 1 : notifyParamVO.getPayType());
        notifyParamVO.setDvyTime(Objects.isNull(notifyParamVO.getDvyTime()) ? new Date() : notifyParamVO.getDvyTime());
        ServerResponseEntity<UserApiVO> userData = null;
        UserApiVO user = null;
        if (!Objects.isNull(notifyParamVO.getUserId())) {
            userData = userFeignClient.getUserAndOpenIdsByUserId(notifyParamVO.getUserId());
            user = userData.getData();
        }
        String openId = "";
        if (Objects.nonNull(user)) {
            if (CollectionUtils.isNotEmpty(user.getBizUserIdList())) {
                openId = user.getBizUserIdList().get(0);
            }
            notifyParamVO.setNickName(user.getNickName());
            // 截取字符串,处理过长名称
            user.setNickName(user.getNickName().substring(0, Math.min(19, user.getNickName().length() - 1)));
        }
        // 分别根据平台和商家的配置进行设置可以发送通知的类型
        // 设置平台的消息通知类型
        setNotifyType(template);
        // 获取对应map
        Map<String, String> smsParam = getSmsParam(notifyParamVO, shopName);
        String content = replaceContent(smsParam, template.getMessage());
        // 保存的通知集合
        List<NotifyLog> notifyLogs = new ArrayList<>();
        if (template.getSms() && BooleanUtils.isFalse(notifyLogStatus)) {
            if (Objects.nonNull(sendTypeEnum) && Objects.equals(sendTypeEnum.getType(), SendTypeEnum.RECEIPT_ORDER.getType()) && StrUtil.isBlank(notifyParamVO.getMobile())) {
                logger.error(shopName + "店铺暂未配置接收通知的手机号，无法推送消息");
                return;
            }
            Boolean isSend = smsLogService.sendMsgSms(template.getTemplateCode(), notifyParamVO.getMobile(), smsParam);
            // 替换消息内容
            addNotifyLog(notifyParamVO, content, template, isSend, NotifyType.SMS.value(), notifyLogs);
        }
        //站内消息
        if (template.getApp() && BooleanUtils.isFalse(notifyLogStatus)) {
            logger.error(shopName + "店铺站内消息");
            notifyParamVO.setShopName(shopName);
            addNotifyLog(notifyParamVO, content, template, false, NotifyType.APP.value(), notifyLogs);
            logger.info(shopName + "消息类型111111" + notifyParamVO.getSendType());
            if (SendTypeEnum.LAUNCH_REFUND.getValue().intValue() == notifyParamVO.getSendType().intValue()) {
                logger.info("商家收到用户申请退款消息通知发送开始");
                openId = "";
                List<String> openIdList = shopDetailFeignClient.getShopMsgUserByShopId(notifyParamVO.getShopId()).getData();
                if (openIdList != null && openIdList.size() > 0) {
                    for (int i = 0; i < openIdList.size(); i++) {
//                        notifyParamVO.setSendType(SendTypeEnum.LAUNCH_REFUND.getValue());
                        sendMessage(template, notifyParamVO, openIdList.get(i), shopName);
                        addNotifyLog(notifyParamVO, content, template, true, NotifyType.MP.value(), notifyLogs);
                    }
                }
                logger.info("商家收到用户申请退款消息通知发送结束");
            }
        }
        //商家收款码
        if (SendTypeEnum.USER_QRCODE_PAY_SUCCESS.getValue().intValue() == notifyParamVO.getSendType().intValue()) {
            logger.info(sendTypeEnum.getType() + "<<商家收款码消息通知发送开始>>" + SendTypeEnum.USER_QRCODE_PAY_SUCCESS.getType());
            List<String> openIdList = shopDetailFeignClient.getShopMsgUserByShopId(notifyParamVO.getShopId()).getData();
            if (openIdList != null && openIdList.size() > 0) {
                for (int i = 0; i < openIdList.size(); i++) {
                    sendMessage(template, notifyParamVO, openIdList.get(i), shopName);
                    addNotifyLog(notifyParamVO, content, template, true, NotifyType.MP.value(), notifyLogs);
                }
            }
            logger.info("商家收款码消息通知发送结束");
        }
        if (SendTypeEnum.USER_PAY_SUCCESS.getValue().intValue() == notifyParamVO.getSendType().intValue()) {
            logger.info("商家新单消息通知发送开始");
            openId = "";
            List<String> openIdList = shopDetailFeignClient.getShopMsgUserByShopId(notifyParamVO.getShopId()).getData();
            if (openIdList != null && openIdList.size() > 0) {
                for (int i = 0; i < openIdList.size(); i++) {
                    notifyParamVO.setSendType(SendTypeEnum.USER_PAY_SUCCESS.getValue());
                    sendMessage(template, notifyParamVO, openIdList.get(i), shopName);
                    addNotifyLog(notifyParamVO, content, template, true, NotifyType.MP.value(), notifyLogs);
                }
            }
            logger.info("商家新单消息通知发送结束");
        }

        if (SendTypeEnum.RECEIPT_ORDER.getValue().intValue() == notifyParamVO.getSendType().intValue()) {
            logger.info("商家收到用户确认收货消息通知发送开始");
            openId = "";
            List<String> openIdList = shopDetailFeignClient.getShopMsgUserByShopId(notifyParamVO.getShopId()).getData();
            if (openIdList != null && openIdList.size() > 0) {
                for (int i = 0; i < openIdList.size(); i++) {
                    notifyParamVO.setSendType(SendTypeEnum.RECEIPT_ORDER.getValue());
                    sendMessage(template, notifyParamVO, openIdList.get(i), shopName);
                    addNotifyLog(notifyParamVO, content, template, true, NotifyType.MP.value(), notifyLogs);
                }
            }
            logger.info("商家收到用户确认收货消息通知发送结束");
        }


        // 公众号
        if (template.getSub() && StrUtil.isNotBlank(openId) && BooleanUtils.isFalse(notifyLogStatus)) {
            logger.error(shopName + "公众号消息开始");
            sendMessage(template, notifyParamVO, openId, shopName);
            logger.error(shopName + "公众号消息结束");
            addNotifyLog(notifyParamVO, content, template, true, NotifyType.MP.value(), notifyLogs);
        }

        if (CollectionUtils.isNotEmpty(notifyLogs)) {
            notifyLogService.saveBatch(notifyLogs);
        }

    }

    @Override
    public void sendOrderNotifyMsgToUser(List<SendNotifyBO> notifyList) {

        SendNotifyBO sendNotifyBO = notifyList.get(0);
        // 注意幂等性，判断下消息是否已经推送过
        if (checkNotifyIsSend(sendNotifyBO.getBizId(), null, sendNotifyBO.getUserId(), sendNotifyBO.getSendType())) {
            return;
        }
        // 批量推送订单事件消息给用户
        List<NotifyParamVO> notifyParamList = mapperFacade.mapAsList(notifyList, NotifyParamVO.class);
        logger.error("发送消息给用户》》》》》》");
        for (NotifyParamVO notifyParamVO : notifyParamList) {
            sendMsg(notifyParamVO);
        }

    }

    @Override
    public void sendOrderNotifyMsgToShop(SendNotifyBO sendNotifyBO) {
        // 注意幂等性，判断下消息是否已经推送过
        if (checkNotifyIsSend(sendNotifyBO.getBizId(), null, sendNotifyBO.getShopId(), sendNotifyBO.getSendType())) {
            return;
        }
        // 发送店铺消息（订单确认收货、买家发起退款、买家已退货,收款码）
        NotifyParamVO paramVO = mapperFacade.map(sendNotifyBO, NotifyParamVO.class);
        logger.error("发送消息给商家》》》》》》");
        sendMsg(paramVO);
    }

    @Override
    public void sendQrCodeNotifyMsgToShop(SendNotifyBO sendNotifyBO) {
        // 注意幂等性，判断下消息是否已经推送过
        if (checkNotifyIsSend(sendNotifyBO.getBizId(), null, sendNotifyBO.getShopId(), sendNotifyBO.getSendType())) {
            return;
        }
        // 发送店铺消息（订单确认收货、买家发起退款、买家已退货,收款码）
        NotifyParamVO paramVO = mapperFacade.map(sendNotifyBO, NotifyParamVO.class);
        sendMsg(paramVO);
    }

    @Override
    public void sendProductNotifyMsgToShop(List<SendNotifyBO> notifyList) {
//        SendNotifyBO sendNotifyBO = notifyList.get(0);
        // 注意幂等性，判断下消息是否已经推送过
//        if(checkNotifyIsSend(sendNotifyBO.getBizId(),null, sendNotifyBO.getShopId(), sendNotifyBO.getSendType())){
//            return;
//        }
        // 批量推送商品事件消息给商家
        List<NotifyParamVO> notifyParamList = mapperFacade.mapAsList(notifyList, NotifyParamVO.class);
        for (NotifyParamVO notifyParamVO : notifyParamList) {
            sendMsg(notifyParamVO);
        }
    }

    @Override
    public void sendOrderToPurchaseNotifyMsgToShop(List<SendNotifyBO> sendNotify) {
        SendNotifyBO sendNotifyBO = sendNotify.get(0);
        // 注意幂等性，判断下消息是否已经推送过
        if (checkNotifyIsSend(sendNotifyBO.getBizId(), null, sendNotifyBO.getShopId(), sendNotifyBO.getSendType())) {
            return;
        }
        // 批量推送商品事件消息给商家
        List<NotifyParamVO> notifyParamList = mapperFacade.mapAsList(sendNotify, NotifyParamVO.class);
        for (NotifyParamVO notifyParamVO : notifyParamList) {
            sendMsg(notifyParamVO);
        }
    }

    @Override
    public void sendActivityNotifyMsgToShop(SendNotifyBO sendNotifyBO) {
        // 注意幂等性，判断下消息是否已经推送过
//        if(checkNotifyIsSend(sendNotifyBO.getBizId(),null,sendNotifyBO.getShopId(), sendNotifyBO.getSendType())){
//            return;
//        }
        // 发送店铺消息
        NotifyParamVO paramVO = mapperFacade.map(sendNotifyBO, NotifyParamVO.class);
        sendMsg(paramVO);
    }

    /**
     * 检查通知是否已经发送
     *
     * @param orderId  订单id
     * @param level    关联id
     * @param userId   接受通知的用户id（店铺id）
     * @param sendType 发送类型
     * @return 结果
     */
    private boolean checkNotifyIsSend(Long orderId, Integer level, Long userId, Integer sendType) {
        int num = notifyLogService.countNotifyByConditions(orderId, level, userId, sendType);
        return num > 0;
    }

    private void setNotifyType(NotifyTemplateVO template) {
        String[] templateCodes = template.getNotifyTypes().split(StrUtil.COMMA);
        List<String> asList = Arrays.asList(templateCodes);
        List<Integer> templates = new ArrayList<>();
        for (String templateStr : asList) {
            templates.add(Integer.valueOf(templateStr));
        }
        template.setSms(false);
        template.setSub(false);
        template.setApp(false);
        for (Integer type : templates) {
            template.setSms(Objects.equals(type, NotifyType.SMS.value()) || template.getSms());
            template.setSub(Objects.equals(type, NotifyType.MP.value()) || template.getSub());
            template.setApp(Objects.equals(type, NotifyType.APP.value()) || template.getApp());
        }
    }

    /**
     * 发送微信模板信息
     */
    private void sendMessage(NotifyTemplateVO template, NotifyParamVO notifyParamVO, String bizUserId, String shopName) {
        WxMpMessage wxMaUniformMessage = new WxMpMessage();
        wxMaUniformMessage.setMpTemplateMsg(true);
        wxMaUniformMessage.setTouser(bizUserId);
        wxMaUniformMessage.setAppid(feignShopConfig.getWxMp().getAppId());
        //TODO 公众号模板消息所要跳转的小程序暂无
//        WxMaUniformMessage.MiniProgram miniProgram = new WxMaUniformMessage.MiniProgram();
//        miniProgram.setAppid(feignShopConfig.getWxMp().getAppId());
//        miniProgram.setPagePath("pages/user/user");
//        wxMaUniformMessage.setMiniProgram(miniProgram);
        //模板id
        wxMaUniformMessage.setTemplate_id(template.getMpCode());
        //模板数据集合
        wxMaUniformMessage.setData(getWxMaTemplateDataList(notifyParamVO, shopName));
        try {
            String responseContent = wxConfig.getWxMpService().post("https://api.weixin.qq.com/cgi-bin/message/template/send", wxMaUniformMessage);
//            JsonObject jsonObject = GsonParser.parse(responseContent);
            logger.info("用户（" + responseContent + "）");
//            if (jsonObject.get("errcode").getAsInt() != 0) {
//                throw new WxErrorException(WxError.fromJson(responseContent, WxType.MiniApp));
//            }
        } catch (WxErrorException e) {
            //用户未关注公众号，导致的消息发送失败异常
            if (Objects.nonNull(e.getError()) && e.getError().getErrorCode() == Constant.WX_MAX_NOT_FOLLOW) {
                logger.info("用户（" + notifyParamVO.getUserId() + "）没有关注公众号，导致消息发送失败");
            }
            //其他异常
            else {
                e.printStackTrace();
            }
        }
    }


    /**
     * 获取微信通知模板列表
     *
     * @param notifyParamVO 通知内容
     * @param shopName      店铺名称
     * @return 微信通知模板列表
     */
    private WxMpTemplateData getWxMaTemplateDataList(NotifyParamVO notifyParamVO, String shopName) {
        Map<Integer, WxMpTemplateData> mpMap = new HashMap<>(24);
        String priceStr = notifyParamVO.getPrice() + "元";
        // 订单微信通知模板
        orderWxMaTemplate(notifyParamVO, shopName, mpMap, priceStr);
        // 团购微信通知模板
        groupWxMaTemplate(notifyParamVO, mpMap, priceStr);
        // 商家微信通知模板
        multishopWxMaTemplate(notifyParamVO, mpMap, priceStr);
        // 会员升级微信通知模板
        JSONObject first = new JSONObject();
        JSONObject keyword1 = new JSONObject();
        JSONObject keyword2 = new JSONObject();
        JSONObject keyword3 = new JSONObject();
        JSONObject keyword4 = new JSONObject();
        JSONObject remark = new JSONObject();
        first.put("value", "会员升级通知");
        keyword1.put("value", notifyParamVO.getLevelName());
        keyword2.put("value", "成功！");
        remark.put("value", "感谢您的支持！");
        mpMap.put(SendTypeEnum.MEMBER_LEVEL.getValue(), new WxMpTemplateData(first, keyword1, remark));

        return mpMap.get(notifyParamVO.getSendType());
    }

    /**
     * @param notifyParamVO 通知信息
     * @param shopName      店铺名称
     * @param mpMap         模板map
     * @param priceStr      价格
     */
    private void orderWxMaTemplate(NotifyParamVO notifyParamVO, String shopName, Map<Integer, WxMpTemplateData> mpMap, String priceStr) {

        String firstData = "亲爱的" + notifyParamVO.getNickName() + ",您在商城购买的宝贝还未付款哦！为确保您心爱的宝贝早日启程、顺利抵达，记得尽早付款哦！";
        JSONObject first = new JSONObject();
        JSONObject keyword1 = new JSONObject();
        JSONObject keyword2 = new JSONObject();
        JSONObject keyword3 = new JSONObject();
        JSONObject keyword4 = new JSONObject();
        JSONObject remark = new JSONObject();
        keyword1.put("value", notifyParamVO.getBizId().toString());
        keyword2.put("value", DateUtil.format(notifyParamVO.getCreateTime(), DatePattern.NORM_DATETIME_PATTERN));
        keyword3.put("value", notifyParamVO.getSpuName());
        remark.put("value", "请您及时付款以免订单过期。");
        first.put("value", firstData);
        mpMap.put(SendTypeEnum.PRESS_PAY.getValue(), new WxMpTemplateData(first, keyword1, keyword2, keyword3, remark));


        first.put("value", "您的退款申请商家已同意");
        keyword1.put("value", notifyParamVO.getBizId().toString());
        keyword2.put("value", notifyParamVO.getSpuName());
        keyword3.put("value", priceStr);
        remark.put("value", "请及时登录商城，查看退款信息");
        mpMap.put(SendTypeEnum.AGREE_REFUND.getValue(), new WxMpTemplateData(first, keyword1, keyword2, keyword3, remark));


        first.put("value", "你好，你的订单已付款成功。");
        keyword1.put("value", DateUtil.format(new Date(), DatePattern.NORM_DATETIME_PATTERN));
        keyword2.put("value", notifyParamVO.getSpuName());
        keyword3.put("value", notifyParamVO.getBizId().toString());
        keyword4.put("value", priceStr);
        remark.put("value", "感谢您的支持！");
        mpMap.put(SendTypeEnum.PAY_SUCCESS.getValue(), new WxMpTemplateData(first, keyword1, keyword2, keyword3, keyword4, remark));

        first.put("value", "你的退款申请被商家驳回，可与商家协商沟通");
        keyword1.put("value", notifyParamVO.getBizId().toString());
        keyword2.put("value", priceStr);
        keyword3.put("value", notifyParamVO.getRejectMessage());
        remark.put("value", "请及时登录商城，查看退款信息");
        mpMap.put(SendTypeEnum.REFUSE_REFUND.getValue(), new WxMpTemplateData(first, keyword1, keyword2, keyword3, remark));

        first.put("value", "尊敬的客户，您的订单提货成功啦。");
        keyword1.put("value", notifyParamVO.getSpuName());
        keyword2.put("value", priceStr);
        keyword3.put("value", notifyParamVO.getProdNum().toString());
        keyword4.put("value", DateUtil.format(new Date(), DatePattern.NORM_DATETIME_PATTERN));
        remark.put("value", "商城感谢您的支持！");
        mpMap.put(SendTypeEnum.WRITE_OFF.getValue(), new WxMpTemplateData(first, keyword1, keyword2, keyword3, keyword4, remark));

        first.put("value", "商品已在送往客官的路上");
        keyword1.put("value", notifyParamVO.getSpuName());
        keyword2.put("value", "已发货");
        keyword3.put("value", notifyParamVO.getDvyName());
        keyword4.put("value", notifyParamVO.getDvyFlowId());
        remark.put("value", DateUtil.format(new Date(), DatePattern.NORM_DATETIME_PATTERN));
        mpMap.put(SendTypeEnum.DELIVERY.getValue(), new WxMpTemplateData(first, keyword1, keyword2, keyword3, keyword4, remark));

        first.put("value", "您有退款单即将超时，请及时联系商家处理");
        keyword1.put("value", shopName);
        keyword2.put("value", "1笔");
        remark.put("value", "如有疑问请及时与客服联系！");
        mpMap.put(SendTypeEnum.REFUND_OUT_TIME.getValue(), new WxMpTemplateData(first, keyword1, keyword2, remark));
    }

    /**
     * 团购微信通知模板
     *
     * @param notifyParamVO 通知信息
     * @param mpMap         模板map
     * @param priceStr      价格
     */
    private void groupWxMaTemplate(NotifyParamVO notifyParamVO, Map<Integer, WxMpTemplateData> mpMap, String priceStr) {
        JSONObject first = new JSONObject();
        JSONObject keyword1 = new JSONObject();
        JSONObject keyword2 = new JSONObject();
        JSONObject keyword3 = new JSONObject();
        JSONObject keyword4 = new JSONObject();
        JSONObject remark = new JSONObject();
        List<WxMaTemplateData> dataList = new ArrayList<>();
        first.put("value", "您参加的拼团因为有效期内未成团，我们将在3个工作日内为您安排自动退款");
        keyword1.put("value", notifyParamVO.getSpuName());
        keyword2.put("value", priceStr);
        keyword3.put("value", "商城");
        remark.put("value", "点击进入订单详情页，查看退款进度！");
        mpMap.put(SendTypeEnum.GROUP_FAIL.getValue(), new WxMpTemplateData(first, keyword1, keyword2, keyword3, remark));

        first.put("value", "恭喜你，拼团已经成功！");
        keyword1.put("value", notifyParamVO.getSpuName());
        keyword2.put("value", priceStr);
        remark.put("value", "请登录商城，查看订单发货信息");
        mpMap.put(SendTypeEnum.GROUP_SUCCESS.getValue(), new WxMpTemplateData(first, keyword1, keyword2, remark));

        first.put("value", "恭喜你，开团已经成功！");
        keyword1.put("value", notifyParamVO.getSpuName());
        keyword2.put("value", priceStr);
        remark.put("value", "快去小程序将参团链接分享给好友进行参团吧！");
        mpMap.put(SendTypeEnum.GROUP_START.getValue(), new WxMpTemplateData(first, keyword1, keyword2, remark));
    }

    /**
     * 商家微信通知模板
     *
     * @param notifyParamVO 通知信息
     * @param mpMap         模板map
     * @param priceStr      价格
     */
    private void multishopWxMaTemplate(NotifyParamVO notifyParamVO, Map<Integer, WxMpTemplateData> mpMap, String priceStr) {
        JSONObject first = new JSONObject();
        JSONObject keyword1 = new JSONObject();
        JSONObject keyword2 = new JSONObject();
        JSONObject keyword3 = new JSONObject();
        JSONObject keyword4 = new JSONObject();
        JSONObject keyword5 = new JSONObject();
        JSONObject remark = new JSONObject();
        first.put("value", "亲，您的订单买家已经确认收货！");
        keyword1.put("value", notifyParamVO.getBizId().toString());
        keyword2.put("value", notifyParamVO.getSpuName());
        keyword3.put("value", "已确认收货");
        remark.put("value", "如有疑问请及时与客服联系！");
        mpMap.put(SendTypeEnum.RECEIPT_ORDER.getValue(), new WxMpTemplateData(first, keyword1, keyword2, keyword3, remark));

        JSONObject firstA = new JSONObject();
        JSONObject keyword1A = new JSONObject();
        JSONObject keyword2A = new JSONObject();
        JSONObject keyword3A = new JSONObject();
        JSONObject keyword4A = new JSONObject();
        JSONObject keyword5A = new JSONObject();
        JSONObject remarkA = new JSONObject();
        firstA.put("value", "店铺有新的退款申请，请及时处理");
        keyword1A.put("value", notifyParamVO.getBizId().toString());
        keyword2A.put("value", DateUtil.format(new Date(), DatePattern.NORM_DATETIME_PATTERN));
        keyword3A.put("value", priceStr);
        keyword4A.put("value", notifyParamVO.getRejectMessage());
        keyword5A.put("value", "待商家确认");
        remarkA.put("value", notifyParamVO.getRemark());
//        dataList.add(new WxMaTemplateData("remark","请您尽快请登录商家后台操作处理。"));
        mpMap.put(SendTypeEnum.LAUNCH_REFUND.getValue(), new WxMpTemplateData(firstA, keyword1A, keyword2A, keyword3A, keyword4A, keyword5A, remarkA));
        JSONObject firstB = new JSONObject();
        JSONObject keyword1B = new JSONObject();
        JSONObject keyword2B = new JSONObject();
        JSONObject keyword3B = new JSONObject();
        JSONObject keyword4B = new JSONObject();
        JSONObject keyword5B = new JSONObject();
        JSONObject remarkB = new JSONObject();
        firstB.put("value", "店铺有新的退款申请，请及时处理");
        keyword1B.put("value", notifyParamVO.getBizId().toString());
        keyword2B.put("value", DateUtil.format(new Date(), DatePattern.NORM_DATETIME_PATTERN));
        keyword3B.put("value", priceStr);
        keyword4B.put("value", notifyParamVO.getRejectMessage());
        keyword5B.put("value", "待商家确认");
        remarkB.put("value", notifyParamVO.getRemark());
//        dataList.add(new WxMaTemplateData("remark","请您尽快请登录商家后台操作处理。"));
        mpMap.put(SendTypeEnum.LAUNCH_REFUND_TO_SUPPLIER.getValue(), new WxMpTemplateData(firstB, keyword1B, keyword2B, keyword3B, keyword4B, keyword5B, remarkB));
        JSONObject firstC = new JSONObject();
        JSONObject keyword1C = new JSONObject();
        JSONObject keyword2C = new JSONObject();
        JSONObject remarkC = new JSONObject();
        firstC.put("value", "你的买家已退货，请及时处理");
        keyword1C.put("value", notifyParamVO.getBizId().toString());
        keyword2C.put("value", notifyParamVO.getRemark());
        remarkC.put("value", "如有疑问请及时与客服联系！");
        mpMap.put(SendTypeEnum.RETURN_REFUND.getValue(), new WxMpTemplateData(firstC, keyword1C, keyword2C, remarkC));
        JSONObject firstD = new JSONObject();
        JSONObject keyword1D = new JSONObject();
        JSONObject keyword2D = new JSONObject();
        JSONObject keyword3D = new JSONObject();

        JSONObject remarkD = new JSONObject();
        firstD.put("value", "您好，您有一笔收款码订单已支付。");
        keyword1D.put("value", priceStr);
        keyword2D.put("value", "收款码订单");
        keyword3D.put("value", DateUtil.format(new Date(), DatePattern.NORM_DATETIME_PATTERN));
        remarkD.put("value", "请登录平台查看余额!");
        mpMap.put(SendTypeEnum.USER_QRCODE_PAY_SUCCESS.getValue(), new WxMpTemplateData(firstD, keyword1D, keyword2D, keyword3D, remarkD));
        JSONObject firstE = new JSONObject();
        JSONObject keyword1E = new JSONObject();
        JSONObject keyword2E = new JSONObject();
        JSONObject keyword3E = new JSONObject();
        JSONObject keyword4E = new JSONObject();
        JSONObject remarkE = new JSONObject();
        firstE.put("value", "你好，你有一笔新的订单已付款成功!");
        keyword1E.put("value", DateUtil.format(new Date(), DatePattern.NORM_DATETIME_PATTERN));
        keyword2E.put("value", notifyParamVO.getSpuName());
        keyword3E.put("value", notifyParamVO.getBizId().toString());
        keyword4E.put("value", priceStr);
        remarkE.put("value", "请登录平台查看并处理！");
        mpMap.put(SendTypeEnum.USER_PAY_SUCCESS.getValue(), new WxMpTemplateData(firstE, keyword1E, keyword2E, keyword3E, keyword4E, remarkE));
    }

    /**
     * 添加消息
     *
     * @notifyParamVO notifyParamVO 参数
     * @notifyParamVO content 消息内容
     * @notifyParamVO template 模板
     * @notifyParamVO isSend 发送状态
     * @notifyParamVO value 发送类型
     * @notifyParamVO notifyLogs 消息集合
     */
    private void addNotifyLog(NotifyParamVO notifyParamVO, String content, NotifyTemplateVO template, Boolean isSend, Integer value, List<NotifyLog> notifyLogs) {
        NotifyLog notifyLog = new NotifyLog();
        notifyLog.setCreateTime(new Date());
        notifyLog.setShopId(notifyParamVO.getShopId());
        notifyLog.setShopName(notifyParamVO.getShopName());
        // 如果大于则为店铺自行接收的消息
        if (notifyParamVO.getSendType() >= Constant.MULTI_SHOP_MESSAGE_TYPE) {
            notifyLog.setRemindId(Objects.nonNull(notifyParamVO.getShopId()) ? notifyParamVO.getShopId().toString() : notifyParamVO.getSupplierId().toString());
        } else {
            notifyLog.setRemindId(notifyParamVO.getUserId().toString());
        }
        notifyLog.setSendType(notifyParamVO.getSendType());
        notifyLog.setBizId(notifyParamVO.getBizId());
        notifyLog.setSpuId(notifyParamVO.getSpuId());
        notifyLog.setShopName(notifyParamVO.getShopName());
        notifyLog.setMessage(content);
        notifyLog.setNickName(notifyParamVO.getNickName());
        notifyLog.setUserMobile(notifyParamVO.getMobile());
        notifyLog.setRemindType(value);
        notifyLog.setTemplateId(template.getTemplateId());
        notifyLog.setStatus(isSend ? 1 : 0);

        notifyLogs.add(notifyLog);

    }


    private Map<String, String> getSmsParam(NotifyParamVO notifyParamVO, String shopName) {
        Map<String, String> smsParam = new HashMap<>(20);
        // 没有orderNumber用orderId
        if (Objects.nonNull(notifyParamVO.getBizId())) {
            smsParam.put("orderNumber", notifyParamVO.getBizId().toString());
        }
        smsParam.put("shopName", shopName);
        smsParam.put("prodName", notifyParamVO.getSpuName());
        if (StrUtil.isNotBlank(notifyParamVO.getNickName())) {
            smsParam.put("nickName", notifyParamVO.getNickName());
        } else {
            smsParam.put("nickName", "用户");
        }
        smsParam.put("levelName", notifyParamVO.getLevelName());
        smsParam.put("date", DateUtil.format(notifyParamVO.getDvyTime(),
                DatePattern.NORM_DATETIME_PATTERN));
        smsParam.put("cancelTime", notifyParamVO.getCancelTime());
        smsParam.put("price", String.valueOf(notifyParamVO.getPrice()));
        smsParam.put("dvyFlowId", notifyParamVO.getDvyFlowId());
        smsParam.put("stationName", notifyParamVO.getStationName());
        smsParam.put("dvyName", notifyParamVO.getDvyName());
        smsParam.put("dvyTime", DateUtil.format(notifyParamVO.getDvyTime(),
                DatePattern.NORM_DATETIME_PATTERN));
        smsParam.put("day", String.valueOf(Constant.MAX_REFUND_APPLY_TIME));
        smsParam.put("hour", notifyParamVO.getHour().toString());
        smsParam.put("spuId", Objects.nonNull(notifyParamVO.getSpuId()) ? notifyParamVO.getSpuId().toString() : null);
        smsParam.put("spuName", Objects.nonNull(notifyParamVO.getSpuName()) ? notifyParamVO.getSpuName() : null);
        smsParam.put("activityId", Objects.nonNull(notifyParamVO.getActivityId()) ? notifyParamVO.getActivityId().toString() : null);
        smsParam.put("activityName", Objects.nonNull(notifyParamVO.getActivityName()) ? notifyParamVO.getActivityName() : null);
        smsParam.put("supplierName", Objects.nonNull(notifyParamVO.getSupplierName()) ? notifyParamVO.getSupplierName() : null);
        return smsParam;
    }


    /**
     * 短信内容替换
     *
     * @notifyParamVO maps 替换内容
     */
    private String replaceContent(Map<String, String> maps, String content) {
        for (Map.Entry<String, String> element : maps.entrySet()) {
            if (StrUtil.isNotBlank(element.getValue())) {
                content = content.replace("${" + element.getKey() + "}", element.getValue());
            }
        }
        return content;
    }

}
